﻿package CutLoad.cookies
{
	import CutLoad.Base;
	import CutLoad.cookies.Fun;
	import CutLoad.cookies.RandNO;
	import CutLoad.transitions.ITransition;
	import CutLoad.transitions.cloud.EasingFollowMe;
	
	import flash.display.Graphics;
	import flash.display.Sprite;
	
	/**
	 * 表格布局,设置一个几行几列的表格，然后可以把元件位置设置进某一个单元格里所在的位置，获该单元格的相对位置.
	 * @author smallerbird mail:smallerbird@gmail.com  site:www.mkigm.com QQ群:49983196
	 * 
	 */	
	public class LayoutTable
	{
		//下个二维数组代表一个表格
		private var arrTable:Array;
		//起始坐标
		private var startx:Number;
		private var starty:Number;
		//
		public function LayoutTable()
		{
		}
		/**
		 * 以表格单元格的位置，做为元件放置位置的参考。 
		 * @param arrConfig 表格配置数组,是一个二维数组，分别表示行和列的长宽:格式:[[第1个单元格长的宽度,第2个单元格长的宽度,第3个单元格长的宽度....],[第1个单元格长的高度,第2个单元格长的高度....]]
		 * @param startx 
		 * @param starty
		 * @return  
		 * 
		 */		
		public function init(arrConfig:Array,startx:Number=0,starty:Number=0):LayoutTable{
			if(arrConfig.length!=2) throw new Error("配制信息格式不对！");
			//缓动效果
			//
			setStartXY(startx,starty);
			//			
			arrTable=new Array();
			var arrTW:Array=arrConfig[0];
			var arrRW:Array=arrConfig[1];
			var xx:Number,yy:Number
			xx=0
			for(var i:Number=0;i<arrTW.length;i++){
				var arrTem:Array=new Array();
				yy=0				
				for(var j:Number=0;j<arrRW.length;j++){
					var tw:Number=arrTW[i];
					var rw:Number=arrRW[j];									
					var obj:Object={x:xx,y:yy,w:tw,h:rw};
					arrTem.push(obj);
					yy+=rw
				}
				xx+=tw
				arrTable.push(arrTem);
			}
			return this
		}
		/**
		 * 设置超始坐标,换句话说就是移动该表格的原点 
		 * @param startx
		 * @param starty
		 * 
		 */		
		public function setStartXY(startx:Number=0,starty:Number=0):void{
			this.startx=startx;
			this.starty=starty
		}
		/**
		 * 获得网格配置数组
		 * 如果设置的表格，每一个单元格的长高都一样的话，可以用这个方法，快速生成所需要的配置数组 
		 * @param rowCount 行的数量
		 * @param colCount 列的数量
		 * @param rowLen 单元格的高
		 * @param colLen 单元格的宽
		 * @return 
		 * 
		 */		
		public static function getArrConfig(rowCount:uint,colCount:Number,rowLen:Number,colLen:Number):Array{
			var arrC:Array=new Array();
			for(var i:Number=0;i<colCount;i++){
				arrC.push(colLen)
			}
			var arrR:Array=new Array();
			for(var j:Number=0;j<rowCount;j++){
				arrR.push(rowLen)
			}
			return [arrC,arrR]
		}
		/**
		 * 获得一个一行一列的表格 
		 * @param w 表格的宽度
		 * @param h 表格的高度
		 * @param startX 开始x
		 * @param startY 开始y
		 * @return 
		 * 
		 */		
		public static function getOneTdLayoutTable(w:Number,h:Number,startX:Number=0,startY:Number=0):LayoutTable{
			var table:LayoutTable=new LayoutTable();
			table.init(LayoutTable.getArrConfig(1,1,h,w),startX,startY);
			return table;
		}
		//
		/**
		 * 获得表格的辅助线
		 * @return 
		 * 
		 */		
		public function DrawTable():Sprite{
			var lineclore:Number=RandNO.getRndColor32();
			var sp:Sprite=new Sprite();
			var gg:Graphics=sp.graphics;			
			for(var i:Number=0;i<arrTable.length;i++){
				for(var j:Number=0;j<arrTable[i].length;j++){
					var tw:Number=arrTable[i][j].w
					var th:Number=arrTable[i][j].h
					var xx:Number=this.startx+arrTable[i][j].x
					var yy:Number=this.starty+arrTable[i][j].y;
					gg.lineStyle(2,lineclore);
					gg.drawRect(xx,yy,tw,th);
				}
			}
			return sp;
		}
		//
		/**
		 * 设置位置坐标
		 * @param t 对齐对象类型0居中,1左上,2上中,3右上,4右中,5右下,6下中,7左下,8左中
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @param transitions 过渡效果类
		 * 
		 */				
		public function setXY(t:uint,u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):void{
			if(t<0||t>8) throw new Error("对齐的类型只能是:0居中,1左上,2上中,3右上,4右中,5右下,6下中,7左下,8左中");
			switch(t){
				case 0:
					this.c(u,r,c,isSetXY,transitions);
					break;
				case 1:
					this.lu(u,r,c,isSetXY,transitions);
					break;
				case 2:
					this.uc(u,r,c,isSetXY,transitions);
					break;
				case 3:
					this.ru(u,r,c,isSetXY,transitions);
					break;
				case 4:
					this.rc(u,r,c,isSetXY,transitions);
					break;
				case 5:
					this.rd(u,r,c,isSetXY,transitions);
					break;
				case 6:
					this.dc(u,r,c,isSetXY,transitions);
					break;
				case 7:
					this.ld(u,r,c,isSetXY,transitions);
					break;
				case 8:
					this.lc(u,r,c,isSetXY,transitions);
					break;
			}
		}
		/**
		 * 居中（也可以使用setXY(0)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @param transitions 注：需要ITransition类的clone({target:操作的目标})
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */		
		public function c(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=wh2(obj.w,u.getShowWidth(),false);
			if(xx<0) xx=0;
			var yy:Number=wh2(obj.h,u.getShowHeight(),false);
			if(yy<0) yy=0;
			/*trace("----c----");
			trace(obj.w+"   "+u.getShowWidth());
			trace(obj.h+"   "+u.getShowHeight());
			trace(xx+"  "+yy);*/
			xx+=obj.x;
			yy+=obj.y;
			//
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy};
		}
		/**
		 * 左上（也可以使用setXY(1)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */	
		public function lu(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=obj.x;
			var yy:Number=obj.y;
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy}
		}
		/**
		 * 上中（也可以使用setXY(2)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */	
		public function uc(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=wh2(obj.w,u.getShowWidth());
			var yy:Number=obj.y
			xx+=obj.x;
			//
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy}
		}
		/**
		 * 右上（也可以使用setXY(3)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */	
		public function ru(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=this.absw(u,obj);
			var yy:Number=obj.y
			xx+=obj.x;
			//
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy}
		}
		/**
		 * 右中（也可以使用setXY(4)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */	
		public function rc(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=this.absw(u,obj);
			var yy:Number=wh2(obj.h,u.getShowHeight());
			xx+=obj.x;
			yy+=obj.y;
			//
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy}
		}
		private var transitions_rd:ITransition;
		/**
		 * 右下（也可以使用setXY(5)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */	
		public function rd(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=this.absw(u,obj);
			var yy:Number=this.absh(u,obj);
			xx+=obj.x;
			yy+=obj.y;
			//
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy}
		}
		/**
		 * 下中（也可以使用setXY(6)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */	
		
		public function dc(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=wh2(obj.w,u.getShowWidth())
			var yy:Number=this.absh(u,obj);
			xx+=obj.x;
			yy+=obj.y;
			//
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy}
		}
		/**
		 * 左下（也可以使用setXY(7)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */	
		
		public function ld(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=obj.x;
			var yy:Number=obj.y+this.absh(u,obj);
			//
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy}
		}
		/**
		 * 左中（也可以使用setXY(8)）
		 * @param u 要设置的元件
		 * @param r 行（注:从0开始）
		 * @param c 列（注:从0开始）
		 * @param isSetXY 是否设置这个元件的位置，默认是设置
		 * @return 坐标,格式：{x:xx,y:yy}
		 * 
		 */	
		
		public function lc(u:Base,r:uint,c:uint,isSetXY:Boolean=true,transitions:ITransition=null):Object{
			var obj:Object=this.arrTable[c][r]
			var xx:Number=obj.x
			var yy:Number=wh2(obj.h,u.getShowHeight());
			yy+=obj.y;
			//
			xx+=this.startx;
			yy+=this.starty;
			if(isSetXY){
				u.setXY(xx,yy,null,transitions);
			}
			return {x:xx,y:yy}
		}
		//中
		private function wh2(v1:Number,v2:Number,isabs:Boolean=true):Number{
			if(isabs){
				return Math.abs((v1-v2)/2);
			}else{
				return (v1-v2)/2;
			}
			
		}
		private function absw(u:Base,obj:Object):Number{
			return Math.abs(u.getShowWidth()-obj.w);
		}
		private function absh(u:Base,obj:Object):Number{
			return Math.abs(u.getShowHeight()-obj.h);
		}
	}
}